package ms.spm.implement;

import java.awt.event.ActionEvent;
import java.io.File;
import java.lang.reflect.Method;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;

import ms.jacrim.framework.XmlConfiguration;
import ms.spm.IAppContext;
import ms.spm.services.ActionCreator;
import ms.spm.services.MethodProvider;
import ms.utils.ExceptionUtil;

import org.w3c.dom.Element;

public class XmlActionCreator implements ActionCreator {

	private final IAppContext context;
	private final XmlConfiguration config;

	public XmlActionCreator(IAppContext context) {
		this.context = context;
		config = context.getService(XmlConfiguration.class);
	}

	@Override
	public Action loadAction(String actId) {
		return loadAction(actId, context);
	}

	@Override
	public Action loadAction(String actId, IAppContext context) {
		StdAction result = new StdAction();

		try {
			MethodProvider provider = context.getService(MethodProvider.class);
			if (config != null) {
				Element e = config.getSource().selectSingleNode(String.format("//actions/action[@id='%s']", actId));
				if (e != null) {
					char s;
					
					String name = e.getAttribute("name");
					
					result.putValue(Action.NAME, name);
					result.putValue(Action.ACTION_COMMAND_KEY, actId);
					String image = e.getAttribute("image");
					if ((new File(image)).exists()) {
						result.putValue(Action.SMALL_ICON, new ImageIcon(image));
					}
					
					if (provider != null) {
						String methodName = e.getAttribute("method");
						if (methodName.length() == 0)
							methodName = actId;
						result.method = provider.resolveMethod(methodName, ActionEvent.class);
						result.target = provider.getMethodTarget(methodName);
					}
				}
			}
		} catch (Exception e) {
			ExceptionUtil.handle(e, context);
		}
		return result;
	}

	class StdAction extends AbstractAction {
		private static final long serialVersionUID = 1L;

		public Method method;
		public Object target;

		@Override
		public void actionPerformed(ActionEvent e) {
			if (method != null)
				try {
					method.invoke(target, e);
				} catch (Exception e1) {
					ExceptionUtil.handle(e1, context);
				}
		}

	}

}
